// 2.2 循环-循环控制语句
/**
 * 有的时候，可能需要多次执行同一块代码。一般情况下，语句是顺序执行的：函数中的第一个语句先执行，接着是第二个语句，依此类推。
 * 编程语言提供了允许更为复杂的执行路径的多种控制结构。
 * 循环语句允许我们多次执行一个语句或语句组
 * 
 * ------------------
 * 循环控制语句
 * 循环控制语句更改执行的正常序列。当执行离开一个范围时，所有在该范围中创建的自动对象都会被销毁。
 * C++ 提供了下列的控制语句。
 * break 语句
 * 终止 loop 或 switch 语句，程序流将继续执行紧接着 loop 或 switch 的下一条语句。
 * 
 * continue 语句
 * 引起循环跳过主体的剩余部分，立即重新开始测试条件。
 * 
 * goto 语句
 * 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。
*/

#include <iostream>

int main(void)
{
  /**
   * break语句
   * C++ 中 break 语句有以下两种用法：
   * 当 break 语句出现在一个循环内时，循环会立即终止，且程序流将继续执行紧接着循环的下一条语句。
   * 它可用于终止 switch 语句中的一个 case。
   * 注意： 如果您使用的是嵌套循环（即一个循环内嵌套另一个循环），break 语句会停止执行最内层的循环，然后开始执行该块之后的下一行代码。
  */
  printf("----------break语句-----------\n");
  int i, j;
  for (i = 0; i < 5; i++)
  {
    for (j = 0; j < 5; j++)
    {
      if ((i * j) % 4 == 0 && i > 0 && j > 0)
      {
        std::cout << "break;"
                  << "i:" << i << " j:" << j << std::endl;
        break;
      }
      std::cout << "i:" << i << " j:" << j << std::endl;
    }
  }

  /**
   * continue语句
   * C++ 中的 continue 语句有点像 break 语句。但它不是强迫终止，continue 会跳过当前循环中的代码，强迫开始下一次循环。
   * 对于 for 循环，continue 语句会导致执行条件测试和循环增量部分。对于 while 和 do...while 循环，continue 语句会导致程序控制回到条件测试上。
  */
  printf("----------continue语句-----------\n");

  int num = 0;
  for (i = 0; i < 5; i++)
  {
    if (i == 3)
    {
      continue;
    }
    num++;
    std::cout << "i: " << i << "\n"
              << "num: " << num << std::endl;
  }

  /**
   * goto语句
   * goto 语句允许把控制无条件转移到同一函数内的被标记的语句。
   * 注意：在任何编程语言中，都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪，使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语句的写法。
   * 语法
   * goto label;
   * ..
   * .
   * label: statement;
   * 在这里，label 是识别被标记语句的标识符，可以是任何除 C++ 关键字以外的纯文本。标记语句可以是任何语句，放置在标识符和冒号（:）后边。
  */
  printf("----------goto语句-----------\n");
  int count = 1;

_Label:
  count++;

  if (count < 3)
  {
    goto _Label;
  }

  std::cout << "count : " << count << std::endl;

  printf("----------end-----------\n");
  return 0;
}